<?php

declare(strict_types=1);

namespace App\Admin;

use App\Entity\AdminUserGroup;
use Presta\ImageBundle\Form\Type\ImageType;
use Sonata\AdminBundle\Admin\AbstractAdmin;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Object\Metadata;
use Sonata\AdminBundle\Route\RouteCollection;
use Sonata\AdminBundle\Show\ShowMapper;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use Symfony\Component\Form\Extension\Core\Type\RepeatedType;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
use Vich\UploaderBundle\Templating\Helper\UploaderHelper;

final class AdminUserAdmin extends AbstractAdmin
{
    private $passwordEncoder;

    protected $uploaderHelper;

    public function __construct($code, $class, $baseControllerName, UserPasswordEncoderInterface $passwordEncoder, UploaderHelper $uploaderHelper)
    {
        parent::__construct($code, $class, $baseControllerName);

        $this->passwordEncoder = $passwordEncoder;
        $this->uploaderHelper = $uploaderHelper;
    }

    protected function configureDatagridFilters(DatagridMapper $datagridMapper): void
    {
        $datagridMapper
            ->add('username')
            ->add('email')
            ->add('admin_user_group_id');
    }

    protected function configureListFields(ListMapper $listMapper): void
    {
        $listMapper
            ->addIdentifier('username')
            ->add('email')
            ->add('admin_user_group_id', 'string', [
                'label' => 'Admin User Group',
                'template' => 'Backend/admin_user/list_admin_user_group_id.html.twig'
            ])
            ->add('created_at', null, [
                'format' => 'Y-m-d H:i:s',
                'timezone' => 'PRC'
            ]);
    }

    protected function configureFormFields(FormMapper $formMapper): void
    {
        $password_help = $this->isCurrentRoute('create') ? '密码应包含数字和字母，长度6~20' : '留空则不更新密码，密码应包含数字和字母，长度6~20';
        $formMapper
            ->with('Basic', ['class' => 'col-md-8'])
                ->add('username')
                ->add('email')
                ->add('password', RepeatedType::class, [
                    'type' => PasswordType::class,
                    'invalid_message' => 'The password fields must match.',
                    'options' => ['attr' => ['class' => 'password-field']],
                    'required' => $this->isCurrentRoute('create'),
                    'first_options' => ['label' => 'Password', 'help' => $password_help],
                    'second_options' => ['label' => 'Repeat Password']
                ])
                ->add('admin_user_group_id', ChoiceType::class, [
                    'label' => 'Admin User Group',
                    'choices' => $this->getAdminUserGroupList(true),
                ])
            ->end()
            ->with('Avatar', ['class' => 'col-md-4'])
                ->add('avatar_file', ImageType::class, [
                    'enable_remote' => false,
                    'max_width' => 800,
                    'max_height' => 800,
                    'preview_width' => '300px',
                    'preview_height' => '300px',
                    'required' => false,
                    'delete_label' => '删除图片',
                    'help' => '图片格式：jpg、png'
                ])
            ->end();
    }

    private function getAdminUserGroupList($is_turn = false)
    {
        $result = [];

        $admin_user_groups = $this->modelManager->findBy(AdminUserGroup::class);
        foreach ($admin_user_groups as $admin_user_group) {
            if ($is_turn) {
                $result[$admin_user_group->getName()] = $admin_user_group->getId();
            } else {
                $result[$admin_user_group->getId()] = $admin_user_group->getName();
            }
        }

        return $result;
    }

    protected function configureShowFields(ShowMapper $showMapper): void
    {
        $showMapper
            ->add('id')
            ->add('email')
            ->add('roles')
            ->add('password');
    }

    public function configureRoutes(RouteCollection $collection)
    {
        parent::configureRoutes($collection); // TODO: Change the autogenerated stub

        $collection->add('profile', 'profile');
        $collection->remove('show');
        $collection->remove('export');
    }

    public function preUpdate($object)
    {
        parent::preUpdate($object); // TODO: Change the autogenerated stub

        if (!empty($object->getPassword())) {
            $new_password = $this->passwordEncoder->encodePassword($object, $object->getPassword());
            $object->setPassword($new_password);
        }
    }

    public function prePersist($object)
    {
        parent::prePersist($object); // TODO: Change the autogenerated stub

        if (!empty($object->getPassword())) {
            $new_password = $this->passwordEncoder->encodePassword($object, $object->getPassword());
            $object->setPassword($new_password);
        }
    }

    public function getTemplate($name)
    {
        switch ($name) {
            case 'edit':
                return 'Backend/admin_user/edit.html.twig';
                break;
            default:
                return parent::getTemplate($name);
                break;
        }
    }

    public function getObjectMetadata($object)
    {
        $url = $this->uploaderHelper->asset($object, 'avatar_file');

        return new Metadata($object->getUsername(), $object->getEmail(), $url);
    }
}
